package com.wechet.serveice.impl;

import com.wechet.DAO.OrderDetailDao;
import com.wechet.DAO.OrderMasterDao;
import com.wechet.common.OrderStatus;
import com.wechet.common.PayStatus;
import com.wechet.common.ProductStatus;
import com.wechet.common.ResultStatus;
import com.wechet.domain.OrderDetail;
import com.wechet.domain.OrderMaster;
import com.wechet.domain.ProductInfo;
import com.wechet.dto.CartDTO;
import com.wechet.dto.OrderDto;
import com.wechet.exception.SellException;
import com.wechet.serveice.OrderService;
import com.wechet.serveice.ProductInfoService;
import com.wechet.utils.OrderMaster2OrderDTO;
import com.wechet.utils.keyUtils;
import okhttp3.WebSocket;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Bean;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by sc on 2017/9/21.
 */
@Service
public class orderServiceImpl implements OrderService {

    @Autowired
    private com.wechet.serveice.WebSocket webSocket;
    @Autowired
    private PayServiceImpl payService;

    @Autowired
    private OrderMasterDao orderMasterDao;

    @Autowired
    private  OrderDetailDao orderDetailDao;

    @Autowired
    private ProductInfoService productInfoService;

    @Override
    @Transactional
    public OrderDto create(OrderDto orderDto) {
        BigDecimal orderAmount  = new BigDecimal(BigInteger.ZERO);
        String orderid = keyUtils.genUniqueKey();
        List<CartDTO> cartDTOList  = new ArrayList<>();
        //查询商品价格数量
        for(OrderDetail orderDetail:orderDto.getOrderDetailList()){
            ProductInfo productInfo = productInfoService.findOne(orderDetail.getProductId());
            if(productInfo == null){
                throw new SellException(ProductStatus.DOWN);
            }
            //总价
            orderAmount  = (productInfo.getProductPrice().multiply(new BigDecimal(orderDetail.getProductQuantity()))).add(orderAmount);
            orderDetail.setDetailId(keyUtils.genUniqueKey());
            orderDetail.setOrderId(orderid);
            BeanUtils.copyProperties(productInfo,orderDetail);
            orderDetailDao.save(orderDetail);
            CartDTO cartDTO = new CartDTO(orderDetail.getProductId(),orderDetail.getProductQuantity());
            cartDTOList.add(cartDTO);


        }
        //ordermaster
        OrderMaster orderMaster = new OrderMaster();
        orderDto.setOrderId(orderid);
        BeanUtils.copyProperties(orderDto,orderMaster);

        orderMaster.setOrderAmount(orderAmount);
        orderMaster.setOrderStatus(OrderStatus.NEW.getCode());
        orderMaster.setPayStatus(PayStatus.NOTPAY.getCode());
        orderMasterDao.save(orderMaster);
        //扣库存

        productInfoService.decreaseStock(cartDTOList);


        webSocket.sendMessage("有新的订单");
        return orderDto;
    }

    @Override
    public OrderDto findOne(String orderId) {
        OrderMaster orderMaster =  orderMasterDao.findOne(orderId);
        if(orderMaster == null){
            throw new SellException(OrderStatus.ORDER_NOT_EXIST);
        }
        List<OrderDetail> orderDetailList = orderDetailDao.findByOrderId(orderId);
        if(CollectionUtils.isEmpty(orderDetailList)){
            throw new SellException(OrderStatus.ORDERDETAIL_NOT_EXIST);
        }
        OrderDto orderDto = new OrderDto();
        BeanUtils.copyProperties(orderMaster,orderDto);
        orderDto.setOrderDetailList(orderDetailList);
        return orderDto;
    }

    @Override
    public Page<OrderDto> findList(String buyeropenid, Pageable pageable)  {
        Page<OrderMaster> orderMasterPage = orderMasterDao.findByBuyerOpenid(buyeropenid,pageable);
        List<OrderDto> orderDtoList = OrderMaster2OrderDTO.convert(orderMasterPage.getContent());
        return  new PageImpl<OrderDto>(orderDtoList,pageable,orderMasterPage.getTotalElements());
    }

    @Override
    @Transactional
    public OrderDto cancel(OrderDto orderDto) {
        OrderMaster orderMaster = new OrderMaster();

        //判断订单状态
        if(!orderDto.getOrderStatus().equals(OrderStatus.NEW.getCode())){
            throw new SellException(OrderStatus.ORDER_STATUS_ERROR);
        }
        //修改订单状态
        orderDto.setOrderStatus(OrderStatus.CANCEL.getCode());
        BeanUtils.copyProperties(orderDto,orderMaster);
        OrderMaster orderMasterUpdateRes = orderMasterDao.save(orderMaster);
        if(orderMasterUpdateRes==null){
            throw  new SellException(ResultStatus.FAILED);
        }
        //返还库存
        if(CollectionUtils.isEmpty(orderDto.getOrderDetailList())){
            throw new SellException(OrderStatus.ORDER_IS_EMPTY);
        }
        List<CartDTO> cartDTOList = orderDto.getOrderDetailList().stream().map(e->new CartDTO(e.getProductId(),e.getProductQuantity())).collect(Collectors.toList());
        productInfoService.increaceStock(cartDTOList);
        //已支付 退款
        if(orderDto.getPayStatus().equals(PayStatus.PAYED)){
            payService.refund(orderDto);
        }
        return orderDto;
    }

    @Override
    @Transactional
    public OrderDto finish(OrderDto orderDto) {
        //判断订单状态
        if(!orderDto.getOrderStatus().equals(OrderStatus.NEW.getCode())){
            throw new SellException(OrderStatus.ORDER_STATUS_ERROR);
        }
        //修改状态
        orderDto.setOrderStatus(OrderStatus.FINISHED.getCode());
        OrderMaster orderMaster = new OrderMaster();
        BeanUtils.copyProperties(orderDto,orderMaster);
        OrderMaster updateOrderMaster =  orderMasterDao.save(orderMaster);
        if(updateOrderMaster==null){
            throw  new SellException(OrderStatus.UPDATE_FAILED);
        }
        return orderDto;
    }

    @Override
    @Transactional
    public OrderDto paid(OrderDto orderDto) {
        //判断订单状态
        if(!orderDto.getOrderStatus().equals(OrderStatus.NEW.getCode())){
            throw new SellException(OrderStatus.ORDER_STATUS_ERROR);
        }
        //判断支付状态
        if(!orderDto.getPayStatus().equals(PayStatus.NOTPAY.getCode())){
            throw  new SellException(OrderStatus.PADYSTATUS_ERROR);
        }
        //修改
        orderDto.setPayStatus(PayStatus.PAYED.getCode());
        OrderMaster orderMaster = new OrderMaster();
        BeanUtils.copyProperties(orderDto,orderMaster);
        OrderMaster updateMaster  = orderMasterDao.save(orderMaster);
        if(updateMaster==null){
            throw  new SellException(OrderStatus.UPDATE_FAILED);
        }
        return orderDto;
    }

    @Override
    public Page<OrderDto> findList(Pageable pageable) {
        Page<OrderMaster> orderPage = orderMasterDao.findAll(pageable);
        List<OrderDto> orderDtoList = OrderMaster2OrderDTO.convert(orderPage.getContent());
        return new PageImpl<OrderDto>(orderDtoList, pageable, orderPage.getTotalElements());
    }
}
